package com.mes.task.manager;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import com.mes.basicdata.dao.DeptFunctionDao;
import com.mes.basicdata.dao.OperationDao;
import com.mes.basicdata.dao.RoutingDao;
import com.mes.basicdata.dao.iface.IEmployeeDao;
import com.mes.basicdata.dao.iface.IPartDao;
import com.mes.basicdata.domain.Employee;
import com.mes.basicdata.domain.Operation;
import com.mes.basicdata.domain.Routing;
import com.mes.basicdata.manager.iface.IPartManager;
import com.mes.check.dao.iface.ICheckTaskDao;
import com.mes.check.manager.iface.ICheckTaskManager;
import com.mes.common.domain.BasicModel;
import com.mes.common.exception.bo.BaseBusinessException;
import com.mes.common.manager.BasicManager;
import com.mes.common.util.SysUtil;
import com.mes.schedule.domain.ScheduleEvent;
import com.mes.schedule.manager.iface.IScheduleEventManager;
import com.mes.schedule.util.ScheduleUtils;
import com.mes.system.manager.iface.ISysOperationAuthManager;
import com.mes.task.manager.iface.IAssignmentWorkCenterManager;
import com.mes.task.manager.iface.IOperationTaskLinkManager;
import com.mes.task.manager.iface.IOperationTaskManager;
import com.mes.task.manager.iface.IPartTaskManager;
import com.mes.task.manager.iface.ITaskPartManager;
import com.mes.task.manager.iface.IWorkRecordManager;
import com.mes.task.dao.OperationTaskDao;
import com.mes.task.dao.iface.IAssignmentDeviceDao;
import com.mes.task.dao.iface.IOperationTaskDao;
import com.mes.task.dao.iface.ITaskDao;
import com.mes.task.dao.iface.IWorkRecordDao;
import com.mes.task.domain.AssignmentDevice;
import com.mes.task.domain.OperationTask;
import com.mes.task.domain.PartTask;
import com.mes.task.domain.Task;
import com.mes.task.domain.WorkRecord;

@Component
public class OperationTaskManager extends BasicManager<OperationTask> implements IOperationTaskManager {

	public final static Log log = LogFactory.getLog(OperationTaskManager.class);

	private String worktimeLookupTableUid = "";

	@Autowired
	private SysUtil sysUtil;
	@Autowired
	private RoutingDao routingDao;
	@Autowired
	private OperationDao operationDao;

	@Autowired
	protected ISysOperationAuthManager sysOperationAuthManager;
	@Autowired
	protected IAssignmentWorkCenterManager assignmentWorkCenterManager;
	@Autowired
	protected IOperationTaskLinkManager operationTaskLinkManager;
	@Autowired
	protected ITaskPartManager taskPartManager;
	@Autowired
	protected IPartTaskManager partTaskManager;
	@Autowired
	protected ICheckTaskManager checkTaskManager;
	@Autowired
	protected ICheckTaskDao checkTaskDao;
	@Autowired
	public ITaskDao taskDao;
	@Autowired
	public IOperationTaskDao operationTaskDao;
	@Autowired
	public IAssignmentDeviceDao assignmentDeviceDao;
	@Autowired
	public IWorkRecordDao workRecordDao;
	@Autowired
	private IScheduleEventManager scheduleEventManager;
	@Autowired
	public IWorkRecordManager workRecordManager;
	@Autowired
	protected IPartDao partDao;
	@Autowired
	protected IPartManager partManager;
	@Autowired
	protected DeptFunctionDao deptFunctionDao;
	@Autowired
	IEmployeeDao employeeDao;

	/**
	 * 工序反馈 功能角色 工人、工段长 功能描述 工人反馈工序任务的加工进度 状态迁移 当反馈确认工序任务完成的时，工序任务的状态置为完成 业务逻辑
	 * １、 工人在如下的格式中填写产出信息中的标示号、合格数量和不合格数量（这里填写的? 格数量和不合格数量为一次反馈的数量） 收料信息 产出信息 图号
	 * 标示号 数量 图号 标示号 合格数量 不合格数量 完成百分比
	 * 
	 * ２、 查看该工序任务下，产出图号和标示号是否已经反馈过，如果反馈过，则将反馈数量? 加，
	 * 
	 * ３、 根据反馈数量累加的结果和工序任务的计划数量，计算工序任务的完成百分比，同时? 馈工序任务对应的零件任务的完成百分比。
	 * 
	 * ４、 每次反馈的时候，给出是否置工序任务完成的选项（改选项的取值遵循下面规则：当?
	 * 计反馈数量>工序任务计划数量时，默认值为置工序任务为完成，当累计反馈数量<工序任务
	 * 计划数量时,默认值为不置工序任务为完成），如果该选项取值为置工序任务为完成，直接?
	 * 置工序任务为完成状态，同时设置工序任务的实际完成时间为当前时间，如果改选项取值为 不置工序任务为完成，则工序任务的状态不做改变，该任务可继续反馈。
	 * 
	 * ５、 生成产出物料的检验要求。
	 * 
	 * ６、 生成一次反馈的加工纪录，主要是某人使用某设备在某个时间产出某些物料。 数据流程 工序任务数据记录在T_Tasks中
	 * 收料信息和产出信息的关系记录在T_Task_Material数据表中 加工记录记录在T_WorkRec数据表中
	 * 产出物料的检验要求记录在M_MaterialCheck数据表中 注意 １、
	 * 工人的反馈要以物料为核心进行反馈，即反馈的语义为：某一个图号、标示号的物料? 这次反馈中完成的合格数量和不合格数量 ２、
	 * 一个产出物料可以经过多次反馈，此时要填写的是该物料完成的百分比 ３、 建议在下列条件下进行反馈： a) 工序任务完成的时候 b)
	 * 每天下午下班的时候
	 * 
	 */

	/**
	 * 两种反馈方式： 1、反馈完成百分比（净百分比） 2、反馈完成数量（净数量）
	 * 
	 * 步骤： 1、程序中只处理百分比，如果输入的是数量，则通过访问Task的计划数量planqty算出其净
	 * 百分比，写入WorkRec(completepercent)
	 * 2、根据净百分比写完成工时(task.taskwork*completecent)，写入WorkRec(CompleteWork)
	 * ，以便以后统计员工工时 3、增加当前工序Task的完成百分比，完成数量，完成工时(completework)，并根据完成百?
	 * 比判断工序任务的完成状态,如果完成，设置实际完成时间(actualfinish)
	 * 4、写入当前工序任务对应的零件任务(parentuid)的完成工时(completework)
	 * 
	 * 一定要处理好的问题：小数，怎样防止出现 完成百分比为99.9999%，但任务未完成的情况
	 * 
	 * 修改：工时统计 task.runtime*completeQty
	 * 
	 */
	@Override
	public void feedbackTask(List<WorkRecord> workRecList) throws Exception {
		WorkRecord oldWorkrec;
		if (workRecList == null) {
			return;
		}
		for (WorkRecord workRec : workRecList) {
			log.info("更新WorkRec的加工记录。。。。");
			if (workRec.getObjectState() == BasicModel.OBJECTSTATE_TOBEADDED) {
				feedbackTaskWorkRec(workRec);// 反馈到任务进度中
				workRecordDao.add(workRec);
			} else if (workRec.getObjectState() == BasicModel.OBJECTSTATE_TOBEDELETED) {
				oldWorkrec = workRecordDao.getById(workRec.getUuid());// 找出以前的反馈记录
				if (oldWorkrec != null) {
					workRecordDao.delete(workRec);// 删除以前的反馈记录
					oldWorkrec.setCompleteQty(-oldWorkrec.getCompleteQty());// 用负数冲销
					feedbackTaskWorkRec(oldWorkrec);// 消除以前对任务的影响
				}
			} else if (workRec.getObjectState() == BasicModel.OBJECTSTATE_TOBEUPDATED) {
				// 找到以前的反馈记录
				oldWorkrec = workRecordDao.getById(workRec.getUuid());// 找出以前的反馈记录
				if (oldWorkrec != null) {
					if (oldWorkrec.getTaskUid().equals(workRec.getTaskUid())
							&& oldWorkrec.getCompleteQty() == workRec.getCompleteQty()) {
						workRecordDao.update(workRec);
					} else {
						workRecordDao.update(oldWorkrec);// 删除以前的反馈记录
						oldWorkrec.setCompleteQty(-oldWorkrec.getCompleteQty());// 用负数冲销
						feedbackTaskWorkRec(oldWorkrec);// 消除以前对任务的影响
						feedbackTaskWorkRec(workRec);// 反馈到任务进度中
						// 记录最后修改人员
						workRec.setCreatorUid(SysUtil.getSessionEmployeeUid());
						workRecordDao.add(workRec);// 添加workrec中的记录
					}
				}
			}
		}
	}

	@Override
	public void feedbackTaskWorkRec(WorkRecord workRec) throws Exception {
		/*
		 * 增加状态控制，是否必须完成后才能检验完成
		 */
		// 非强制完成
		if ((workRec.getWorkType() == 903 || workRec.getWorkType() == 904) || !isCompleteAfterCheck(null)) {
			// 获得任务初始数据
			OperationTask task = this.getById(workRec.getTaskUid());
			if (task != null) {
				log.info("更新工序任务进度数据。。。。");
				task.setCompleteQty(
						(task.getCompleteQty() == null ? 0 : task.getCompleteQty()) + workRec.getCompleteQty());
				// 任务完成数不能为负的限制
				if (task.getCompleteQty() < 0)
					throw new Exception("反馈任务完成总数不能小于0!");

				// 如果非切割性工序,任务的完成数必须小于计划数,
				log.debug("complete:" + task.getCompleteQty() + "-->plan:" + task.getPlanQty());
				if (task.getCompleteQty() > task.getPlanQty()) { // 对完成数大于计划数的任务进行限制,如果单件产出比=1,则不允许完成数大于计划数.
					// 由于第一阶段工艺员可能未将拆分工序标识出
					String allowExcessFeedBackString = sysUtil.getProperty("Task.allowExcessFeedBack");
					if (allowExcessFeedBackString != null && Boolean.parseBoolean(allowExcessFeedBackString)) {
						this.updateOpTaskPlanQty(task.getTaskUid(), task.getCompleteQty().intValue());// 用该完成数量更新后续工序的数量
					} else {
						Operation operation = this.operationDao.getById(task.getOperationUid());
						if (operation != null && operation.getBaseYield() != null && operation.getBaseYield() > 1)
							this.updateOpTaskPlanQty(task.getTaskUid(), task.getCompleteQty().intValue());// 用该完成数量更新后续工序的数量
						else
							throw new Exception("反馈任务完成总数不能大于计划数!");
					}
				}
				// 保存完成数
				this.update(task);

				// 更新任务的完成数量，如果全部完成更新任务状态和完成日期
				if (task.getCompleteQty() >= task.getPlanQty()) {
					this.finishOperationTask(task.getTaskUid());
				} else {// 如果没有全部完成，则进行状态判断
					// todo
					// 应该有清除完成cancelfinish方法
					// 如果本来是完成状态，则属于取消完成
					if (task.getTaskState() >= OperationTask.TASKSTATE_COMPLETED) {
						task.setActualFinish(null);// 清除任务的实际完成时间
						// 先要置状态后再去改变工序距离
						if (task.getCompleteQty() > 0)// 如果完成数量大于0，则置位为已开始
							task.setTaskState(OperationTask.TASKSTATE_STARTED);
						else
							task.setTaskState(OperationTask.TASKSTATE_DISPATCHED);

						// 重新刷新当前工序和工序距离
						if (task.getParentTaskUid() != null)
							this.refreshTaskDistance(task.getParentTaskUid(), null, null);

					}
					if (task.getCompleteQty() > 0)// 如果完成数量大于0，则置位为已开始
						task.setTaskState(OperationTask.TASKSTATE_STARTED);

					this.update(task);
				}

				log.info("更新零件任务进度数据。。。。");
				// 零件任务的完成数量至为末道工序的完成数量
				PartTask partTask = task.getPartTask();
				if (partTask != null) {
					if (task.getTaskState() >= OperationTask.TASKSTATE_COMPLETED
							&& partTaskManager.isPartTaskFinish(task.getParentTaskUid())) {
						partTaskManager.finishPartTask(task.getParentTaskUid());
					}
					// 如果还没有开始，则设置为开始
					else if (!partTask.getTaskState().equals(PartTask.TASKSTATE_STARTED)) {
						partTaskManager.startPartTask(task.getParentTaskUid());
					}
				}
			}

			try {
				// 发出调度事件
				this.sendWorkRecScheduleEvent(workRec, task);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		// 下面这一部分暂时觉得意义不大，而且多维护一个派工状态增加了很多无谓的工作量
		// lqm 以后应该直接去掉
		log.info("更新派工项记录。。。。");
		AssignmentDevice assn = null;
		assn = assignmentDeviceDao.getById(workRec.getAssignmentUid());
		if (assn != null) {
			assn.setCompleteQty(assn.getCompleteQty() + workRec.getCompleteQty());
			if (assn.getCompleteQty() >= assn.getAssnQty()) {
				assn.setAssnState(2);
				assn.setActualFinish(new Date());
			} else {
				assn.setAssnState(1);
				assn.setActualFinish(null);
			}
			assignmentDeviceDao.update(assn);
		}

	}

	/**
	 * 此函数用来修改工序任务的数量，从某道工序开始往下更新，最后更新零件任务在制数量(planqty)---dbc
	 * 
	 * @param taskUID
	 * @param newQty
	 * @throws Exception
	 */
	public void updateOpTaskPlanQty(String taskUid, int newQty) throws Exception {
		if (newQty <= 0) {
			// lqm 临时这样做
			log.error("**********强制将工序任务数量修改为0");
			return;
		}
		log.info("开始设置工序任务在制数量" + taskUid);
		OperationTask curTask = operationTaskDao.getById(taskUid);

		List<OperationTask> objTasks = operationTaskDao.getOperationTasksByPartTaskUid(curTask.getParentTaskUid(),
				false);

		float preQty = 0;
		float lastQty = 0;
		String tmptaskuid = "";
		boolean isModify = false;

		// 更新工序任务在制数量
		for (OperationTask tmptask : objTasks) {
			if (isModify == false) {
				if (taskUid.equals(tmptask.getUuid())) {
					isModify = true;
					preQty = newQty;
				}
			}

			if (isModify == true) {
				if (tmptask.getTaskType() != OperationTask.TASKTYPE_SAMPLE) {
					Operation tmproutine = operationDao.getById(tmptask.getOperationUid());
					float singleout = 1;
					if (tmproutine != null && !taskUid.equals(tmptaskuid)) {
						singleout = Float.parseFloat(tmproutine.getBaseYield().toString());
					}
					lastQty = singleout * preQty;

					if (tmptask.getTaskState() < 209) {
						if (lastQty <= 0) {
							log.info("设置任务在制数小于或者等于0，系统发生意外退出此程序" + tmptaskuid);
							throw new Exception("不能设置任务在制数小于或等于0!");
						} else {
							log.info("设置任务工序任务在制数：" + tmptaskuid);
							tmptask.setPlanQty(lastQty);
						}
					}
					// edit by lqm 2006-9-27
					// 如果完成数量大于计划数量，则设置任务为完成，但不设置任务状态
					if (lastQty <= tmptask.getCompleteQty()) {
						tmptask.setTaskState(OperationTask.TASKSTATE_COMPLETED);
						tmptask.setActualFinish(taskDao.getMaxFeedBackDate(tmptask.getUuid()));
						log.info("因为修改修改工序数量导致工序任务设置为完成" + tmptask.getUuid());
					}

					tmptask.setObjectState(BasicModel.OBJECTSTATE_TOBEUPDATED);
					operationTaskDao.update(tmptask);
					preQty = lastQty;
				}
			}
		}

		// 更新零件任务在制数量
		if (curTask.getParentTaskUid() != null) {
			partTaskManager.updatePlanQty(curTask.getParentTaskUid(), lastQty);
		}
		log.info("结束设置工序任务在制数量" + taskUid);
	}

	/**
	 * 本方法通过获取配置参数决定任务的完工节点是在工人反馈还是检验完成的节点。 @author 秦金涛 @param
	 * deptId:员工所属部门，employeeId: 员工编号 @return boolean;
	 * true:完工节点为检验完成；false:完工节点为工人反馈
	 */
	@SuppressWarnings("deprecation")
	public boolean isCompleteAfterCheck(String masterShopId) throws Exception {
		String completeByCheck = sysUtil.getProperty("Task.CompleteByCheck");
		// 设置参数为检验完成后任务才完成，并且角色是检验员,并且检验服务的部门是在指定的部门内才满足条件
		if (completeByCheck != null && completeByCheck.equals("on")) {
			// 如果人员是检验，就可以执行更新task
			String deptId = (masterShopId == null) ? sysUtil.getSessionDeptUid() : masterShopId;

			if (deptId != null && this.isDeptInScope(deptId)) {
				return true;// 否则就要限制执
			}

			if (deptId == null) {
				throw new Exception("OperateTaskManager:isCompleteAfterCheck获得部门编号为空，会话可能过期，请重新登录系统");
			}
		}
		return false;
	}

	// 判断传入的dept是否在配置范围内，在:true,不在：false
	@SuppressWarnings("deprecation")
	private boolean isDeptInScope(String deptId) throws Exception {// true:表示可以修改cotask
		String strDepts = ((String) sysUtil.getProperty("Task.CompleteByCheck.dept"));
		if (strDepts != null && strDepts.length() > 0) {
			String[] depts = strDepts.split(",");
			for (String tempDept : depts) {
				if (deptId.startsWith(tempDept)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 强制完成工序任务
	 */
	@Override
	public void forceFinishTask(String taskUid, String workerUid) throws Exception {
		Date date = new Date();
		OperationTask operationTask = (OperationTask) this.getById(taskUid);

		if (operationTask == null) {
			return;
		}
		// 在workRec中记录强制完成操作者
		WorkRecord workRecord = new WorkRecord();
		workRecord.setTaskUid(taskUid);
		workRecord.setWorkerUid(workerUid);
		workRecord.setCreatorUid(workerUid);
		// 刚好反馈一个差值
		workRecord.setCompleteQty(operationTask.getPlanQty()
				- (operationTask.getCompleteQty() == null ? 0 : operationTask.getCompleteQty()));
		workRecord.setWorkDate(date);
		workRecord.setWorkType(WorkRecord.FORCE_FINISH_TASK);
		workRecord.setNotes("强制完成");

		workRecordManager.add(workRecord);

		operationTask.setCompleteQty(operationTask.getPlanQty());
		this.finishOperationTask(operationTask);

	}

	/**
	 * 完成工序任务
	 *
	 * @param operationTask
	 */
	@Override
	public void finishOperationTask(OperationTask operationTask) {
		if (operationTask.getTaskState() >= OperationTask.TASKSTATE_COMPLETED) {
			return;
		}
		// 如果零件任务还未开始，则设置为开始
		PartTask partTask = operationTask.getPartTask();
		if (partTask != null) {
			if (partTask.getTaskState() < PartTask.TASKSTATE_STARTED) {
				partTask.setTaskState(PartTask.TASKSTATE_STARTED);
			}
		}
		// 临时这么用
		// 注意
		// if (operationTask.getCompleteQty()==null ||
		// operationTask.getCompleteQty() <= 0)
		// operationTask.setCompleteQty(operationTask.getPlanQty());
		operationTask.setActualFinish(new Date());
		operationTask.setTaskState(OperationTask.TASKSTATE_COMPLETED);
		// 将完成工序的工序距离置空
		operationTask.setTaskDistance(null);
		try {
			this.update(operationTask);
		} catch (Exception e) {
			e.printStackTrace();
		}

		this.refreshTaskDistance(operationTask.getParentTaskUid(), operationTask.getOperationId(), null);

		try {
			this.forceFinishTaskBefore(operationTask);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void finishOperationTask(String taskUid) throws Exception {
		OperationTask operationTask = (OperationTask) operationTaskDao.getById(taskUid);
		this.finishOperationTask(operationTask);
	}

	/**
	 * 此方法判断是否限制强制完成非本单位的任务。
	 * 
	 * @param taskUID
	 * @return true:限制该操作，false:不限制该操作(默认)
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	private boolean isForceFinishOpen() throws Exception {
		String canForceFinish = sysUtil.getProperty("Task.deptForceFinish");
		if (canForceFinish != null && canForceFinish.equals("on")) {// 限制强制完成
			return true;
		}
		return false;
	}

	/**
	 * 判断传入的dept是否在配置范围内，在:true,不在：false
	 * 
	 * @param deptId
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("deprecation")
	private boolean isForceFinishDeptInScope(String deptId) throws Exception {// true:表示可以修改cotask
		String strDepts = ((String) sysUtil.getProperty("Task.deptForceFinish.dept"));
		if (strDepts != null && strDepts.length() > 0) {
			String[] depts = strDepts.split(",");
			for (String tempDept : depts) {
				if (deptId.startsWith(tempDept)) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public void refreshTaskDistance(String partTaskUid, Float afterOperationId, Integer beginTaskDistance) {
		// if()

		log.debug("开始刷新工序距离" + partTaskUid);
		// TODO Auto-generated method stub
		OperationTask currentOperationTask = null;
		List<OperationTask> operationTaskList = null;
		try {
			if (afterOperationId == null)
				operationTaskList = operationTaskDao.getOperationTasksByParentUid(partTaskUid);
			else
				operationTaskList = operationTaskDao.getOperationTasksByParentUid(partTaskUid, afterOperationId);

			if (operationTaskList == null || operationTaskList.size() == 0)
				return;
			int iDistance = beginTaskDistance == null ? 0 : beginTaskDistance;
			int iSize = operationTaskList.size();

			for (int j = 0; j < iSize; j++) {
				OperationTask operationTask = operationTaskList.get(j);

				// 如果已经完成
				if (operationTask.isFinished()) {

					iDistance = 0;
					continue;
				}
				if (iDistance == 0) {

					currentOperationTask = operationTask;
				}
				// log.debug("开始刷新工序" + operationTask+",工序");
				operationTask.setTaskDistance(iDistance);

				iDistance++;

				this.update(operationTask);

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (currentOperationTask != null) {
			PartTask partTask = currentOperationTask.getPartTask();
			if (partTask != null) {
				partTask.setCurrentOperationTaskUid(currentOperationTask.getTaskUid());
				partTask.setCurrentOperationTask(currentOperationTask);
			}
		}
	}

	@Override
	public boolean isProductDutyDept(String sessionDeptUid, String taskMasterShopUid) {
		// TODO Auto-generated method stub
		// DeptFunctionDAO deptFunctionDAO = (DeptFunctionDAO) SpringUtils
		// .getBean("deptFuntionDAO");
		String serviceDeptUid = deptFunctionDao.getProductServiceDeptUid(sessionDeptUid);
		return (taskMasterShopUid.startsWith(serviceDeptUid)) ? true : false;
	}

	@Override
	public void lockOperationTask(String taskUid, Date planStart, Date planFinish, String notes) throws Exception {

		OperationTask operationTask = this.getById(taskUid);
		if (operationTask == null)
			throw new Exception("根据uid无法找到任务" + taskUid);

		SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		ScheduleEvent scheduleEvent = new ScheduleEvent();
		String scheduleUid = ScheduleUtils.getScheduleUid(operationTask.getPartTask().getMasterShopUid());
		scheduleEvent.setScheduleUid(scheduleUid);
		scheduleEvent.setEventType(ScheduleEvent.EVENTTYPE_LOCK_TASK);
		scheduleEvent.setKeyUid(taskUid);

		Element taskElement = new Element("Task");
		taskElement.setAttribute("taskUid", operationTask.getTaskUid());
		// taskElement.setAttribute("coTaskState",String.valueOf(operationTask.getCoTaskState()));
		// 开始时间
		taskElement.setAttribute("planStart", (planStart) == null ? "" : formatDate.format(planStart));
		taskElement.setAttribute("planFinish", (planFinish == null ? "" : formatDate.format(planFinish)));
		taskElement.setAttribute("notes", operationTask.getNotes() == null ? "" : operationTask.getNotes());

		Format format = Format.getCompactFormat();

		format.setEncoding("UTF-8");
		format.setIndent("  ");
		XMLOutputter outputter = new XMLOutputter(format);

		scheduleEvent.setEventContent(outputter.outputString(taskElement));

		scheduleEvent.setEventState(ScheduleEvent.EVENTSTATE_DRAFT);
		scheduleEvent.setSourceUid(taskUid);
		scheduleEvent.setSourceType("用户锁定");
		scheduleEvent.setCreatorUid(SysUtil.getSessionEmployeeUid());
		scheduleEvent.setCreateTime(new Date());
		/**
		 * 避免频繁更新
		 */
		if (operationTask.getPartTask() != null && operationTask.getPartTask().getMasterShopUid() != null)
			scheduleEventManager.SaveOrUpdateBySource(operationTask.getPartTask().getMasterShopUid(), scheduleEvent);

	}

	// 根据工步获取工序
	private OperationTask getParentOperationTask(OperationTask operationTask) {
		PartTask partTask = operationTask.getPartTask();
		List<OperationTask> opSet = partTask.getOperationTasks();
		for (OperationTask operationTask2 : opSet) {
			if (operationTask2.getOperationUid().equals(operationTask.getOperation().getParentOpUid())) {
				operationTask2.setCompleteQty(operationTask.getCompleteQty());
				return operationTask2;
			}
		}
		return null;
	}

	/**
	 * 获取某道工序之前的所有工序任务
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<OperationTask> getOperationTasksBefore(String taskUid) throws Exception {
		OperationTask operationTask = (OperationTask) this.getById(taskUid);
		float operation_id = operationTask.getOperationId();

		List<OperationTask> opList2 = new ArrayList<OperationTask>();
		if (!(taskUid == null || "".equals(taskUid))) {
			List<OperationTask> opList = this.operationTaskDao.getOperationTaskByPartUidAndBatchNum(
					operationTask.getPartUid(), operationTask.getBatchNum(), true, null);
			for (OperationTask operationTask2 : opList) {
				if (operationTask2.getOperationId() < operation_id) {
					opList2.add(operationTask2);
				} else {
					break;
				}
			}
		}
		// 移除工步所属的工序任务
		if (operationTask.getTaskType().startsWith("5")) {
			OperationTask parentOperationTask = this.getParentOperationTask(operationTask);
			opList2.remove(parentOperationTask);
		}

		return opList2;
	}

	/**
	 * 强制完成某道工序之前的所有未完成的工序任务
	 */

	@Override
	public void forceFinishTaskBefore(String taskUid, String workerUid) throws Exception {
		List<OperationTask> list = this.getOperationTasksBefore(taskUid);
		for (OperationTask operationTask : list) {
			if (operationTask.getTaskState() != OperationTask.TASKSTATE_COMPLETED) {
				this.forceFinishTask(operationTask.getTaskUid(), workerUid);
			}
		}
	}

	/**
	 * 强制完成该工序之前的工序
	 *
	 * @param operationTask
	 */
	private void forceFinishTaskBefore(OperationTask operationTask) throws Exception {
		boolean allowBeforeFinish = false;
		PartTask partTask = operationTask.getPartTask();
		if (partTask == null || partTask.getMasterShopUid() == null)
			return;

		String deptUid = sysUtil.getSessionDeptUid();
		allowBeforeFinish = this.isNeedforceFinishTaskBefore(deptUid);

		if (!allowBeforeFinish)
			return;

		List<OperationTask> operationTaskList = this.operationTaskDao.getUnFinishTasksByPartTask(partTask.getTaskUid(),
				operationTask.getOperationId());
		if (operationTaskList != null && operationTaskList.size() > 0) {
			for (OperationTask bo : operationTaskList) {
				// tod
				// 这里放得有些另类
				// bo.setActualFinish(new Date());
				bo.setTaskState(OperationTask.TASKSTATE_COMPLETED);
				// 将完成工序的工序距离置空
				bo.setTaskDistance(null);
			}
			this.update(operationTaskList);
		}
	}

	@Override
	public void startOperationTask(String taskUid) throws Exception {
		// TODO Auto-generated method stub
		OperationTask operationTask = (OperationTask) this.operationTaskDao.getById(taskUid);
		this.startOperationTask(operationTask);
	}

	/**
	 * 开始工序任务
	 *
	 * @param operationTask
	 */
	@Override
	public void startOperationTask(OperationTask operationTask) throws Exception {
		if (operationTask.getTaskState() >= OperationTask.TASKSTATE_STARTED) {
			return;
		}
		Calendar calendar = Calendar.getInstance();
		operationTask.setActualStart(calendar.getTime());
		operationTask.setTaskState(OperationTask.TASKSTATE_STARTED);
		this.update(operationTask);

		/**
		 * 如果首件检验时间为空，则将设置 todo,应该是否需要三检，最好能够根据设备进行判断
		 */
		// if(operationTask.getNeedCheck())
		// 首件检验任务产生时机
		String allowCreateFirstCheck = sysUtil.getProperty("createFirstCheckTaskTime");
		if (allowCreateFirstCheck != null && allowCreateFirstCheck.equalsIgnoreCase("startTask"))
			this.checkTaskManager.createFirstCheckTask3(operationTask);

		// 缺省工时应该参数化
		double estiPreopTime = operationTask.getEstiPreOpTime() == null ? 480 : operationTask.getEstiPreOpTime();
		double estiRunTime = operationTask.getEstiRunTime() == null ? 30 : operationTask.getEstiRunTime();
		calendar.add(Calendar.MINUTE, (int) Math.round(estiPreopTime + estiRunTime));
		// 预期送达时间
		this.checkTaskManager.setFCT3PlanSendByTaskUid(operationTask.getTaskUid(), calendar.getTime());

	}

	/**
	 * 通过部门编号判断是否强制完成之前的工序任务
	 *
	 * @param deptUid
	 * @return
	 */
	public boolean isNeedforceFinishTaskBefore(String deptUid) {
		boolean b = false;
		try {
			String strDept = sysUtil.getProperty("forceFinishTaskBeforeDept");
			if (strDept != null && strDept.length() > 0) {
				String[] aDept = strDept.split(",");
				for (String str : aDept) {
					if (deptUid.startsWith(str)) {
						b = true;
						break;
					}
				}
			}
			return b;
		} catch (Exception e) {
			log.error(e);
			return false;
		}
	}

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
//	/**
//	 * 该方法来之原来系统的OperateTaskManager类
//	 *
//	 * 强制完成任务 1)遍历所有该工序任务零件任务的所有未完成的工序任务，并修改这些任务的计划数量为该工序任务的完成数量;
//	 * 2)新的计划数量为各道工序计划数量乘该道工序的完成情况的合格百分比；
//	 *
//	 * 注意事项： 如果有需要返修的情况，应该在返修之后强制完成；
//	 *
//	 */
//	 public void forceFinishTask(String taskUid, String employeeUid) throws
//	 Exception {
//	 OperationTask operationTask = this.getById(taskUid);
//	 if (operationTask == null) {
//	 return;
//	 }
//	 String sessionDeptId = sysUtil.getSessionDeptUid();
//	 String masterShop = operationTask.getMasterShopUid();
//	
//	 // 此操作编号为 forceFinishTask
//	 String sysOperationUid = "forceFinishTask";
//	 // 进行功能验证
//	 sysOperationAuthManager.validOperationAuth(sysOperationUid,
//	 SysUtil.getSessionEmployeeUid());
//	
//	 if (!(masterShop == null || this.isProductDutyDept(sessionDeptId,
//	 masterShop))) {
//	 boolean canForceFinish = this.isForceFinishOpen();
//	 if (canForceFinish && this.isForceFinishDeptInScope(sessionDeptId)) {//
//	 限制非本车间任务被强制完成
//	 throw new Exception("工序【" + operationTask.getOperationIdDesc() + " " +
//	 operationTask.getTaskName()
//	 + "】任务不能由本部门强制完成！");
//	 }
//	 }
//	 List<WorkRecord> workRecList = new ArrayList<WorkRecord>(1);
//	 WorkRecord workrec = new WorkRecord();
//	 // 在workRec中记录强制完成操作者
//	 workrec.setTaskUid(taskUid);
//	 workrec.setWorkerUid(employeeUid);
//	 workrec.setCreatorUid(employeeUid);
//	 workrec.setWorkType(903);// 强制完成,参见workreocord类
//	 workrec.setCompleteQty(operationTask.getPlanQty() -
//	 operationTask.getCompleteQty());// 刚好反馈一个差值
//	 workrec.setWorkDate(new java.sql.Timestamp(new Date().getTime()));
//	 workrec.setCreateTime(workrec.getWorkDate());
//	 workrec.setNotes("强制完成");
//	 workrec.setCompleteState(4);
//	 workrec.setDispatchType("0");
//	 workrec.setObjectState(BasicModel.OBJECTSTATE_TOBEADDED);
//	 workRecList.add(workrec);
//	 this.feedbackTask(workRecList);
//	 workrec = null;
//	 workRecList = null;
//	 }
//
//	public Integer updateOperationTaskCalcWorktime(OperationTask task)
//	 throws Exception {
//	 if (task == null) {
//	 throw new Exception("task为空!");
//	 } else if (task.getUuid() == null) {
//	 throw new Exception("task的uid为空！");
//	 }
//	 DBHandler dbhandler = new DBHandler();
//	 ResultSet rs = null;
//	 Integer isEstitimeUsed = null;
//	 try {
//	 String sql = null;
//	 if (worktimeLookupTableUid == null
//	 || worktimeLookupTableUid.equals("")) {
//	 sql = "select uniqueid from b_lookup_table_header where table_id =
//	 'WorkTimeTable'";
//	 dbhandler.createPreparedStatement(sql);
//	 rs = dbhandler.getResultSet();
//	 if (rs.next()) {
//	 worktimeLookupTableUid = rs.getString("uniqueid");
//	 } else {
//	 throw new Exception("没有找到真值表！");
//	 }
//	 dbhandler.closeStmt();
//	 }
//	
//	 sql = " select nvl(tt.is_esti_used,0) as is_esti_used from t_tasks tt
//	 where tt.taskuid = ?";
//	 dbhandler.createPreparedStatement(sql);
//	 dbhandler.stmt.setString(1, task.getUuid());
//	 rs = dbhandler.getResultSet();
//	
//	 if (rs.next()) {
//	 isEstitimeUsed = rs.getInt("is_esti_used");
//	 } else {
//	 throw new Exception("找不到相关任务！");
//	 }
//	 dbhandler.closeStmt();
//	
//	 if (isEstitimeUsed >= 1) {
//	 return 0;
//	 }
//	
//	 sql = "select btd.value,tt.taskuid"
//	 + " from t_tasks tt"
//	 + " left join b_part_number bp on bp.part_number = tt.part_number"
//	 + " left join b_optype bo on bo.optype = tt.optype"
//	 + " left join r_resource rr on rr.resuid = tt.workcenteruid"
//	 + " left join b_lookup_table_detail btd on btd.parameter1_value ="
//	 + " nvl(rr.worktime_ratio_level,2)"
//	 + " and btd.parameter2_value ="
//	 + " nvl(bp.worktime_ratio_level,2)"
//	 + " and btd.parameter3_value ="
//	 + " nvl(bo.worktime_ratio_level,2)"
//	 + " and btd.headeruid = ?" + " where tt.tasktype like '2%'"
//	 + " and tt.taskuid = ?";
//	 dbhandler.createPreparedStatement(sql);
//	 dbhandler.stmt.setString(1, worktimeLookupTableUid);
//	 dbhandler.stmt.setString(2, task.getUuid());
//	 String value = null;
//	 rs = dbhandler.getResultSet();
//	 if (rs.next()) {
//	 value = rs.getString("value");
//	 } else {
//	 return -1;
//	 }
//	 dbhandler.closeStmt();
//	
//	 int nextPreTime = 0;
//	 int nowPreTime = 0;
//	 int nextRunTime = 0;
//	 int nowRunTime = 0;
//	 sql = " select (case when nvl(tt.preoptime, 0) = 0 then"
//	 + " nvl(bo.default_pretime, 30) else"
//	 + " (tt.preoptime * ?) end) as nextPreTime,"
//	 + " mmdn(tt.estipretime) as nowPreTime,"
//	 + " (case when nvl(tt.runtime, 0) = 0 then"
//	 + " nvl(bo.default_runtime, 30) else"
//	 + " (tt.runtime * ?) end) as nextRunTime,"
//	 + " mmdn(tt.estiruntime) as nowRunTime"
//	 + " from t_tasks tt"
//	 + " left join b_optype bo on bo.optype = tt.optype"
//	 + " where tt.taskuid = ?";
//	 dbhandler.createPreparedStatement(sql);
//	 dbhandler.stmt.setFloat(1, Float.parseFloat(value));
//	 dbhandler.stmt.setFloat(2, Float.parseFloat(value));
//	 dbhandler.stmt.setString(3, task.getUuid());
//	 rs = dbhandler.getResultSet();
//	 if (rs.next()) {
//	 nextPreTime = rs.getInt("nextPreTime");
//	 nowPreTime = rs.getInt("nowPreTime");
//	 nextRunTime = rs.getInt("nextRunTime");
//	 nowRunTime = rs.getInt("nowRunTime");
//	 } else {
//	 return -1;
//	 }
//	 dbhandler.closeStmt();
//	
//	 if (nextPreTime != nowPreTime || nextRunTime != nowRunTime) {
//	 sql = "update t_tasks tt set tt.estipretime = mmen(?),tt.estiruntime =
//	 mmen(?) where tt.taskuid = ?";
//	 dbhandler.createPreparedStatement(sql);
//	 dbhandler.stmt.setInt(1, nextPreTime);
//	 dbhandler.stmt.setInt(2, nextRunTime);
//	 dbhandler.stmt.setString(3, task.getUuid());
//	 dbhandler.executeUpdate();
//	 dbhandler.closeStmt();
//	 return 1;
//	 } else {
//	 return 0;
//	 }
//	
//	 } catch (Exception e) {
//	 e.printStackTrace();
//	 throw new Exception(e.getMessage());
//	 } finally {
//	 dbhandler.close();
//	 }
//	 }
//
//	public List<OperationTask> getOperationTask(String parentuid, int scope) throws Exception {
//		if (scope == this.UNFINISHED) {
//			Conditions conditions = new Conditions();
//			conditions.addCondition(new ConditionObjectLink("parentTaskUid", ConditionObject.EQUAL_OPERATOR, parentuid,
//					ConditionObject.STRING_TYPE));
//			conditions.addCondition(new ConditionObjectLink("taskState", ConditionObject.LESS_OPERATOR, "209",
//					ConditionObject.DOUBLE_TYPE));
//			conditions.addCondition(new ConditionObjectLink("order", ConditionObject.BY_OPERATOR, "operationId",
//					ConditionObject.STRING_TYPE), ConditionObjectLink.END_TYPE);
//			return this.get(conditions);
//		}
//		return null;
//	}
//
//	public Float getCalcPreTime(OperationTask task)
//	 throws Exception {
//	 if (task == null || task.getUuid() == null) {
//	 throw new Exception("task为空或者taskuid为空！");
//	 }
//	 DBHandler dbhandler = new DBHandler();
//	 try {
//	 String sql = "select (case "
//	 + " when mmdn(tt.estipretime) = 0 then "
//	 + " (case when nvl(tt.preoptime, 0) = 0 then "
//	 + " (bo.default_pretime) else (tt.preoptime * tt.worktime_ratio) end)"
//	 + " else mmdn(tt.estipretime) end) as preworktime "
//	 + " from t_tasks tt "
//	 + " left join b_optype bo on bo.optype = tt.optype "
//	 + " where tt.taskuid = ?";
//	 dbhandler.createPrep                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                nTask.setTaskState(OperationTask.TASKSTATE_READY);
//	 if (operationTask.getTaskType() == null)
//	 operationTask.setTaskType(OperationTask.TASKTYPE_NORMAL);
//	 if (operationTask.getDeptUid() == null)
//	 operationTask.setDeptUid(MMUtils.getSessionDeptId());
//	 if (operationTask.getMasterShopUid() == null)
//	 operationTask.setMasterShopUid(MMUtils.getSessionDeptId());
//	 return super.add(object);
//	 }
//
//	public void updateOperationTask(PartTask partTask, OperationTask oldOperationTask, Operation newOperation,
//			String sessionEmployeeUid) throws Exception {
//		if (oldOperationTask == null)
//			throw new Exception("要变更的工序内容不能为空！");
//		if (newOperation == null)
//			throw new Exception("插入工序内容不能为空！");
//		if (partTask == null)
//			throw new Exception("插入工序时零组件任务不能为空！");
//
//		// 更新任务基本信息
//		oldOperationTask.setName(newOperation.getOperationName());
//		oldOperationTask.setOperationUid(newOperation.getUuid());
//		oldOperationTask.setOperationIdDesc(newOperation.getOperationIdDesc());
//
//		WorkCenter wc = newOperation.getWorkCenter();
//		if (wc != null) // 工作中心
//		{
//			oldOperationTask.setMasterShopUid(wc.getDeptUid());
//			oldOperationTask.setWorkCenter(wc);
//			oldOperationTask.setDispatchGrade(wc.getDispatchGrade());
//		}
//		this.update(oldOperationTask);
//
//		// 更新工作中心分配
//		List<AssignmentWorkCenter> assignmentWorkCenterList = assignmentWorkCenterManager.findByProperty("taskUid",
//				oldOperationTask.getUuid());
//		if (assignmentWorkCenterList != null && assignmentWorkCenterList.size() > 0) {
//			AssignmentWorkCenter assignmentWorkCenter = assignmentWorkCenterList.get(0);
//			assignmentWorkCenter.setTaskUid(oldOperationTask.getUuid());
//			assignmentWorkCenter.setWorkCenterUid(wc.getUuid());
//			assignmentWorkCenter.setCreatorUid(sessionEmployeeUid);
//			assignmentWorkCenter.setCreateTime(new Date());
//			assignmentWorkCenterManager.update(assignmentWorkCenter);
//		}
//
//		// 更新taskPart
//		Set<TaskPart> taskParts = oldOperationTask.getTaskParts();
//		if (taskParts != null && taskParts.size() > 0)
//			taskPartManager.delete(taskParts);
//
//		Set<OperationPart> operationParts = newOperation.getOperationParts();
//		if (operationParts != null && operationParts.size() > 0) {
//			for (OperationPart operationPart : operationParts) {
//				TaskPart taskPart = new TaskPart();
//				taskPart.setTaskUid(oldOperationTask.getUuid());
//				taskPart.setPartUid(operationPart.getConsumedPartUid());
//				double producedQty = operationPart.getProducedQuantity() > 0 ? operationPart.getProducedQuantity() : 1;
//				taskPart.setQtyreq(oldOperationTask.getPlanQty() * operationPart.getConsumedQuantity() / producedQty);
//				taskPart.setCreatorUid(sessionEmployeeUid);
//
//				taskPartManager.add(taskPart);
//			}
//
//		}
//
//		// 如果遇到检验类型的更改,修改一下检验任务
//		// lqm todo
//		// 这个处理其实相当没有必要，应该去修改一下检验任务产生时机
//
//		List<CheckTask> checkTasks = this.checkTaskDAO.getUnFinishCheckTasksByTask(oldOperationTask.getTaskUid());
//		if (checkTasks != null && checkTasks.size() > 0) {
//			// 如果是检验工序
//			if (newOperation.getOperationType() != null
//					&& newOperation.getOperationType().equals(Operation.OPERATION_TYPE_CHECK)) {
//				for (CheckTask checkTask : checkTasks) {
//					// 将流检设置成汇总检验
//					if (checkTask.getCheckTaskType() != null
//							&& checkTask.getCheckTaskType().equals(CheckTask.OPERATIONCHECK))
//						checkTask.setCheckTaskType(CheckTask.SUMMARYCHECK);
//				}
//			} else {
//				for (CheckTask checkTask : checkTasks) {
//					// 将汇检设置成流检
//					if (checkTask.getCheckTaskType() != null
//							&& checkTask.getCheckTaskType().equals(CheckTask.SUMMARYCHECK))
//						checkTask.setCheckTaskType(CheckTask.OPERATIONCHECK);
//				}
//			}
//
//			this.checkTaskManager.update(checkTasks);
//
//		}
//
//	}
//
//	/**
//	 * add by lhy 工序任务反馈的时候，会根据需要（属性配置）判断是否需要将之前的工序强制完成
//	 */
//
//	/*
//	 *
//	 * (non-Javadoc)
//	 *
//	 * @see
//	 * com.mes.task.manager.iface.IOperationTaskManager#submitCompleteQty(com.
//	 * mes.task.persistence.domain.OperationTask, float)
//	 */
//	/*
//	 * public void submitCompleteQty(OperationTask operationTask, float
//	 * completeQty) throws Exception { log.info("更新工序任务进度数据。。。。");
//	 * operationTask.setCompleteQty(operationTask.getCompleteQty()+
//	 * completeQty); // 任务完成数不能为负的限制 if (operationTask.getCompleteQty() < 0)
//	 * throw new Exception("反馈任务完成总数不能小于0!"); // 如果非切割性工序,任务的完成数必须小于计划数, if
//	 * (operationTask.getCompleteQty() > operationTask.getPlanQty()) { //
//	 * 对完成数大于计划数的任务进行限制,如果单件产出比=1,则不允许完成数大于计划数. Operation operation
//	 * =operationTask.getOperation(); if (operation != null) { if
//	 * (operation.getBaseYield()== 1) throw new Exception("反馈任务完成总数不能大于计划数!");
//	 * else updateOpTaskPlanQty(operationTask, (int) operationTask
//	 * .getCompleteQty());// 用该完成数量更新后续工序的数量 } } // 如果物料与任务的图号不相等，则自动继承任务图号与任务批次
//	 * // 更新任务的完成数量，如果全部完成更新任务状态和完成日期 if (operationTask.getCompleteQty() >=
//	 * operationTask.getPlanQty()) {
//	 * operationTask.setTaskState(OperationTask.TASKSTATE_COMPLETED);
//	 * operationTask.setActualFinish(new Date()); } else {// 如果没有全部完成，则进行状态判断
//	 * operationTask.setActualFinish(null);// 清除任务的实际完成时间 if
//	 * (operationTask.getCompleteQty() > 0)// 如果完成数量大于0，则置位为已开始
//	 * operationTask.setTaskState(OperationTask.TASKSTATE_STARTED); else { if
//	 * (operationTask.getAssignmentEquiments().size() > 0)
//	 * operationTask.setTaskState(OperationTask.TASKSTATE_DISPATCHED);//
//	 * 如果已经派工则置为已派工 else
//	 * operationTask.setTaskState(OperationTask.TASKSTATE_READY);// 否则置为已分派 } }
//	 * this.update(operationTask);
//	 *
//	 *
//	 * log.info("更新零件任务进度数据。。。。"); // 零件任务的完成数量至为末道工序的完成数量 PartTask partTask =
//	 * operationTask.getParentTask(); if (partTask != null) { if
//	 * (isLastOperation(operationTask)) {
//	 * partTask.setCompleteQty(operationTask.getCompleteQty()); if
//	 * (partTask.getCompleteQty() >= partTask.getPlanQty()) {
//	 * partTask.setTaskState(PartTask.TASKSTATE_COMPLETED);
//	 * partTask.setActualFinish(new Date()); } else {
//	 * partTask.setTaskState(PartTask.TASKSTATE_STARTED); if
//	 * (partTask.getActualStart() == null) partTask.setActualStart(new Date());
//	 * partTask.setActualFinish(null); } } // 如果还没有开始，则设置为开始 else if
//	 * (partTask.getTaskState() <=PartTask.TASKSTATE_STARTED) {
//	 * partTask.setTaskState(PartTask.TASKSTATE_STARTED); if
//	 * (partTask.getActualStart() == null) partTask.setActualStart(new Date());
//	 * partTask.setActualFinish(null); } IPartTaskManager partTaskManager
//	 * =(IPartTaskManager)SpringUtils.getBean("partTaskManager");
//	 * partTaskManager.update(partTask); } }
//	 */
//
//	/**
//	 * 判断一个工序是否是零件的最后一道工序
//	 *
//	 * @param operationTask
//	 * @return
//	 */
//	@SuppressWarnings("unchecked")
//	private Boolean isLastOperation(OperationTask operationTask) {
//		PartTask partTask = operationTask.getParentTask();
//		List<OperationTask> opList = this.operationTaskDAO.getOperationTaskByPartUidAndBatchNum(
//				operationTask.getPartUid(), operationTask.getBatchNum(), true, null);
//		if (opList != null && opList.size() > 0) {
//			if (operationTask.getOperationId().equals(opList.get(opList.size() - 1).getOperationId())) {
//				return true;
//			}
//		}
//		return false;
//	}
//
//	private Date getMaxFeedBackDate(OperationTask operationTask) {
//		Date maxFeedBackDate = new Date(0);
//		Set<WorkRecord> workRecords = operationTask.getWorkRecords();
//		for (WorkRecord workRecord : workRecords) {
//			if (workRecord.getWorkDate().after(maxFeedBackDate))
//				maxFeedBackDate = workRecord.getWorkDate();
//		}
//
//		return maxFeedBackDate;
//
//	}
//
//	// 此函数用来修改工序任务的数量，从某道工序开始往下更新，最后更新零件任务在制数量(planqty)---dbc
//	private void updateOpTaskPlanQty(OperationTask operationTask, int newQty) throws Exception {
//		PartTask partTask = operationTask.getParentTask();
//		IPartTaskManager partTaskManager = (IPartTaskManager) SpringUtils.getBean("partTaskManager");
//
//		Set<OperationTask> operationTasks = partTask.getOperationTasks();
//
//		double preQty = 0;
//		double lastQty = 0;
//		String tmptaskuid = "";
//		boolean isModify = false;
//
//		// 更新工序任务在制数量
//		for (OperationTask tmptask : operationTasks) {
//			if (isModify == false) {
//				if ((operationTask.getUuid()).equals(tmptask.getUuid())) {
//					isModify = true;
//					preQty = newQty;
//				}
//			}
//
//			if (isModify == true) {
//				if (!tmptask.getTaskType().equalsIgnoreCase("205")) {
//					Operation operation = tmptask.getOperation();
//					double singleout = 1;
//					if (operation != null && !((operationTask.getUuid()).equals(tmptask.getUuid()))) {
//						singleout = operation.getBaseYield();
//					}
//					lastQty = singleout * preQty;
//
//					if (tmptask.getTaskState() < 209) {
//						if (lastQty <= 0) {
//							log.info("设置任务在制数小于或者等于0，系统发生意外退出此程序" + tmptaskuid);
//							throw new Exception("不能设置任务在制数小于或等于0!");
//						} else {
//							log.info("设置任务工序任务在制数：" + tmptaskuid);
//							tmptask.setPlanQty((float) lastQty);
//						}
//					}
//					// edit by lqm 2006-9-27
//					// 如果完成数量大于计划数量，则设置任务为完成，但不设置任务状态
//					if (lastQty <= tmptask.getCompleteQty()) {
//						tmptask.setTaskState(TaskManager.oFINISHED);
//						tmptask.setActualFinish(getMaxFeedBackDate(tmptask));
//						log.info("因为修改修改工序数量导致工序任务设置为完成" + tmptask.getUuid());
//					}
//					this.update(tmptask);
//					preQty = lastQty;
//				}
//			}
//		}
//
//		// 更新零件任务在制数量
//		if (partTask != null) {
//			log.info("开始设置零件任务在制数量" + partTask.getUuid());
//			partTask.setPlanQty((float) lastQty);
//			partTaskManager.update(partTask);
//		}
//
//		// 更新Material中的数量
//		log.info("开始设置物料在制数" + operationTask.getUuid());
//		mm.material.object.MaterialEng clsMaterialEng = new MaterialEng();
//		mm.material.object.MaterialS clsMaterialS;
//		mm.material.object.Material clsMaterial;
//		clsMaterialS = (MaterialS) clsMaterialEng.searchItems(" part_number='" + operationTask.getPartUid()
//				+ "' and batchnum='" + operationTask.getBatchNum() + "' and sn='0' ");
//		if (clsMaterialS.getCount() > 0) {
//			clsMaterial = (Material) clsMaterialS.get(0);
//			clsMaterial.setMaterialQty((float) lastQty);// 设置物料数量增加至此数量
//			clsMaterial.setUpdateMode(Material.UPDATEMODE_UPDATE);
//			log.info("设置物料在制数");
//			clsMaterial.updateItem();
//		}
//		clsMaterialEng = null;
//		clsMaterialS = null;
//		clsMaterial = null;
//
//		log.info("结束设置工序任务在制数量:" + operationTask.getUuid());
//	}
//
//	public void submitCompleteQty(OperationTask operationTask, float completeQty) throws Exception {
//		// TODO Auto-generated method stub
//
//	}
//
//	public OperationTask getOperationTask(PartTask partTask, Operation operation) throws Exception {
//		// TODO Auto-generated method stub
//		return null;
//	}
//
//	/**
//	 * 改变顺序相当于一次删除和添加后的网络处理
//	 */
//	public void changeSeq(PartTask partTask, OperationTask operationTask, OperationTask refOperationTask, String pos,
//			String sessionEmployeeUid) throws Exception {
//		deleteNetPro(operationTask);
//		// 网络路线与排序id号的处理
//		insertNetPro(partTask, operationTask, refOperationTask, "After", sessionEmployeeUid);
//
//	}
//
//	@Override
//	public void dispatchOperatioinTask(String taskUid) throws Exception {
//		OperationTask task = (OperationTask) this.getById(taskUid);
//		// 处理低优先级的任务,低优先级任务设置为无效
//		// 这里应该写入参数化规则
//		if (task != null) {
//			// throw new Exception("无法找到对应任务！");
//			// 这个逻辑114暂时没有用
//
//			// if (task.getPriority() >= 4) {
//			// assn.setEffective(false);
//			// }
//
//			// 设置任务派工状态
//			if (task.getTaskState() <= OperationTask.TASKSTATE_READY) {
//				task.setTaskState(OperationTask.TASKSTATE_DISPATCHED);
//				this.update(task);
//
//				// 首件检验任务产生时机
//				String allowCreateFirstCheck = this.projectProperty.getPropertyValue("createFirstCheckTaskTime");
//				if (allowCreateFirstCheck != null && allowCreateFirstCheck.equalsIgnoreCase("dispatchTask"))
//					this.checkTaskManager.createFirstCheckTask3(taskUid);
//
//				this.checkTaskManager.createOperationCheckTask(taskUid);
//				log.info("Task state changed to be dispatched.");
//			}
//		}
//
//	}
//
//	@Override
//	public OperationTask getById(Serializable id) {
//		// TODO Auto-generated method stub
//		return (OperationTask) super.getById(id);
//	}
//
//	@Override
//	public Date getPredFinish(String taskUid) {
//		Date predFinish = null;
//
//		try {
//			OperationTask oTask = this.getById(taskUid);
//			if (oTask != null) {
//				predFinish = MMUtils.MIN_DATE;
//
//				for (OperationTaskLink link : oTask.getPredOperationTaskLinks()) {
//					OperationTask predOTask = link.getPreOperationTask();
//					if (!(predOTask.isFinished()) && predOTask.getPlanFinish() != null
//							&& predOTask.getPlanFinish().after(predFinish))
//						predFinish = predOTask.getPlanFinish();
//				}
//			}
//		} catch (RuntimeException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//		return (predFinish != null && predFinish != MMUtils.MIN_DATE) ? predFinish : null;
//	}
//
//	@Override
//	public Date getSuccStart(String taskUid) {
//		Date succStart = null;
//		try {
//			OperationTask oTask = this.getById(taskUid);
//			if (oTask != null) {
//				succStart = MMUtils.MAX_DATE;
//				for (OperationTaskLink link : oTask.getSuccOperationTaskLinks()) {
//					OperationTask succOTask = link.getSucOperationTask();
//					if (succOTask.getPlanStart() != null && succOTask.getPlanStart().before(succStart))
//						succStart = succOTask.getPlanStart();
//				}
//			}
//		} catch (RuntimeException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//		return (succStart != null && succStart != MMUtils.MAX_DATE) ? succStart : null;
//
//	}
//
//	public IOperationTaskDAO getOperationTaskDAO() {
//		return operationTaskDAO;
//	}
//
//	public void setOperationTaskDAO(IOperationTaskDAO operationTaskDAO) {
//		this.operationTaskDAO = operationTaskDAO;
//	}
//
//	public ScheduleEventManager getScheduleEventManager() {
//		return scheduleEventManager;
//	}
//
//	public void setScheduleEventManager(ScheduleEventManager scheduleEventManager) {
//		this.scheduleEventManager = scheduleEventManager;
//	}
//
//	/**
//	 * 通过反馈记录完成零件和工序记录的更新
//	 */
//	@Override
//	public void feedbackTaskWorkRec(WorkRecord workRecord) throws Exception {
//
//		Date date = new Date();
//		// if (workRecord.getDispatchtype() == 0) {
//		OperationTask operationTask = (OperationTask) this.getById(workRecord.getTaskUid());
//		if (operationTask != null) {
//			log.info("更新工序任务进度数据。。。。");
//			operationTask.setCompleteQty((operationTask.getCompleteQty() == null ? 0 : operationTask.getCompleteQty())
//					+ workRecord.getCompleteQty());
//
//			// 任务完成数不能为负的限制
//			if (operationTask.getCompleteQty() < 0)
//				throw new Exception("反馈任务完成总数不能小于0!");
//
//			if (operationTask.getCompleteQty() >= operationTask.getPlanQty()) {
//				operationTask.setTaskState(OperationTask.TASKSTATE_COMPLETED);
//				operationTask.setActualFinish(date);
//			} else {// 如果没有全部完成，则进行状态判断
//				operationTask.setActualFinish(null);// 清除任务的实际完成时间
//				if (operationTask.getCompleteQty() > 0)// 如果完成数量大于0，则置位为已开始
//					operationTask.setTaskState(OperationTask.TASKSTATE_STARTED);
//				else {
//					Assignment clsAssn = new Assignment();
//					if (clsAssn.getDispatchsByTaskuid(operationTask.getTaskUid()).size() > 0)
//						operationTask.setTaskState(OperationTask.TASKSTATE_DISPATCHED);// 如果已经派工则置为已派工
//					else
//						operationTask.setTaskState(OperationTask.TASKSTATE_READY);// 否则置为已分派
//					clsAssn = null;
//				}
//
//			}
//
//			/**
//			 * add by dwm 工序任务反馈的时候，会根据需要（属性配置）判断是否需要将之前的工序强制完成
//			 */
//			// if (operationTask.getTaskState() ==
//			// operationTask.TASKSTATE_COMPLETED) {
//			// usermanagement.MMProperty mmp = new MMProperty();
//			// if ("true".equalsIgnoreCase(mmp
//			// .getProperty("needForceFinishTaskBefore"))) {
//			// forceFinishTaskBefore(operationTask.getTaskUid(),
//			// workRecord.getWorkerUid());
//			// }
//			// this.forceFinishTaskBefore(operationTask.getTaskUid(),
//			// workRecord.getWorkerUid());
//			// }
//			this.forceFinishTaskBefore(operationTask.getTaskUid(), workRecord.getWorkerUid());
//			log.info("更新零件任务进度数据。。。。");
//			// this.update(operationTask);
//			// 零件任务的完成数量至为末道工序的完成数量
//			IPartTaskManager partTaskManager = (IPartTaskManager) SpringUtils.getBean("partTaskManager");
//
//			PartTask partTask = operationTask.getParentTask();
//			// 陈亮todo
//			if (operationTask.getTaskType().startsWith("5")) {
//				// 判断是否为最后一道工步
//				if (this.isLastOperationStep(operationTask)) {
//					OperationTask parentOperationTask = this.getParentOperationTask(operationTask);
//					if (parentOperationTask != null) {
//						parentOperationTask.setCompleteQty(operationTask.getCompleteQty());
//						this.finishOperationTask(parentOperationTask);
//						this.addWorkRecordByOperationTask(parentOperationTask);
//					}
//				}
//
//			}
//
//			if (partTask != null) {
//
//				if (this.isLastOperation(operationTask)) {
//					if (partTask.getTaskState() != PartTask.TASKSTATE_COMPLETED) {
//						partTask.setCompleteQty(operationTask.getCompleteQty());
//						partTaskManager.finishPartTask(partTask);
//					}
//				}
//				// 如果还没有开始，则设置为开始
//				else if (partTask.getTaskState() != PartTask.TASKSTATE_STARTED) {
//					partTask.setTaskState(PartTask.TASKSTATE_STARTED);
//					if (partTask.getActualStart() == null)
//						partTask.setActualStart(date);
//					if (partTask.getActualStart() != null)
//						partTask.setActualFinish(null);
//
//				}
//
//				OperationTask nextOperationTask = this.getNextOperationTask(operationTask);
//				if (nextOperationTask != null) {
//					partTask.setCurrentOperationTaskUid(nextOperationTask.getTaskUid());
//				} else {
//					partTask.setCurrentOperationTaskUid(null);
//				}
//
//				partTaskManager.update(partTask);
//
//			}
//
//		}
//
//		// }
//
//	}
//
//	// 获取前道工序
//	public OperationTask getPrevOperationTask(OperationTask operationTask) {
//		PartTask partTask = operationTask.getParentTask();
//		Set<OperationTask> opSet = partTask.getOperationTasks();
//		OperationTask prevOperationTask = null;
//		for (OperationTask operationTask2 : opSet) {
//			if (operationTask2.getTaskUid().equals(operationTask.getTaskUid())) {
//				return prevOperationTask;
//			} else {
//				prevOperationTask = operationTask2;
//			}
//		}
//		return prevOperationTask;
//	}
//
//	// 获取后道工序
//	public OperationTask getNextOperationTask(OperationTask operationTask) {
//		PartTask partTask = operationTask.getParentTask();
//		Set<OperationTask> opSet = partTask.getOperationTasks();
//
//		List<OperationTask> opList = new ArrayList<OperationTask>(opSet);
//		OperationTask nextOperationTask = null;
//		for (int i = opList.size() - 1; i >= 0; i--) {
//			OperationTask operationTask2 = opList.get(i);
//			if (operationTask2.getTaskUid().equals(operationTask.getTaskUid())) {
//				return nextOperationTask;
//			} else {
//				nextOperationTask = operationTask2;
//			}
//		}
//		return nextOperationTask;
//	}
//
//	private boolean isLastOperationStep(OperationTask operationTask) {
//		PartTask partTask = operationTask.getParentTask();
//		List<OperationTask> opList = this.operationTaskDAO.getOperationTaskByPartUidAndBatchNum(
//				operationTask.getPartUid(), operationTask.getBatchNum(), false, null);
//		if (opList != null && opList.size() > 0) {
//			for (OperationTask operationTask2 : opList) {
//				if (operationTask.getOperation().getParentOpUid()
//						.equals(operationTask2.getOperation().getParentOpUid())) {
//					if (operationTask.getOperationId().equals(operationTask2.getOperationId())) {
//						return true;
//					} else {
//						return false;
//					}
//				}
//			}
//
//		}
//		return false;
//	}
//
//	/**
//	 * 强制完成工序任务 但不改变完成数量
//	 */
//
//	public void forceFinishTaskNoCompleteQty(String taskUid, String workerUid) throws Exception {
//		Date date = new Date();
//		OperationTask operationTask = (OperationTask) this.getById(taskUid);
//
//		if (operationTask == null) {
//			return;
//		}
//		// 在workRec中记录强制完成操作者
//		WorkRecord workRecord = new WorkRecord();
//		workRecord.setTaskUid(taskUid);
//		workRecord.setWorkerUid(workerUid);
//		workRecord.setCreatorUid(workerUid);
//		// 刚好反馈一个差值
//		// workRecord.setCompleteQty(operationTask.getPlanQty()
//		// - (operationTask.getCompleteQty() == null ? 0 : operationTask
//		// .getCompleteQty()));
//		workRecord.setWorkType(WorkRecord.FORCE_FINISH_TASK_NO_COMPLETEQTY);
//		workRecord.setWorkDate(date);
//		workRecord.setNotes("差额强制完成");
//
//		workRecordManager.add(workRecord);
//
//		// operationTask.setCompleteQty(operationTask.getPlanQty());
//		this.finishOperationTask(operationTask);
//
//	}
//
//	/*
//	 * 完工反馈
//	 */
//	@Override
//	public void submitOperationTask(OperationTask operationTask) throws Exception {
//
//		WorkRecord workRecord = this.addWorkRecordByOperationTask(operationTask);
//		this.feedbackTaskWorkRec(workRecord);
//
//	}
//
//	// 根据工序任务添加反馈记录
//	private WorkRecord addWorkRecordByOperationTask(OperationTask operationTask) throws Exception {
//		WorkRecord workRecord = new WorkRecord();
//		workRecord.setTaskUid(operationTask.getTaskUid());
//		workRecord.setWorkerUid(MMUtils.getSessionEmployeeId());
//		workRecord.setCreatorUid(MMUtils.getSessionEmployeeId());
//		workRecord.setCompleteQty(operationTask.getPlanQty());
//		workRecord.setWorkDate(new Date());
//		workRecordManager.add(workRecord);
//		return workRecord;
//	}
//
//	/**
//	 * 单工序返工
//	 */
//	@Override
//	public void cancelOperationTask(OperationTask operationTask) throws Exception {
//		this.deleteRecordByOperationTask(operationTask);
//		IPartTaskManager partTaskManager = (IPartTaskManager) SpringUtils.getBean("partTaskManager");
//		PartTask partTask = operationTask.getParentTask();
//		operationTask.setActualFinish(null);
//		operationTask.setTaskState(OperationTask.TASKSTATE_DISPATCHED);
//		this.update(operationTask);
//
//		if (operationTask.getTaskType().startsWith("5")) {
//			if (this.isLastOperationStep(operationTask)) {
//				OperationTask parentOperationTask = this.getParentOperationTask(operationTask);
//				parentOperationTask.setActualFinish(null);
//				parentOperationTask.setTaskState(OperationTask.TASKSTATE_STARTED);
//				this.update(parentOperationTask);
//				this.deleteRecordByOperationTask(parentOperationTask);
//
//			}
//		}
//		if (partTask != null) {
//			if (this.isLastOperation(operationTask)) {
//				partTask.setCompleteQty(operationTask.getCompleteQty());
//				partTask.setActualFinish(null);
//				partTask.setTaskState(PartTask.TASKSTATE_STARTED);
//			}
//			partTask.setCurrentOperationTaskUid(operationTask.getTaskUid());
//			partTaskManager.update(partTask);
//		}
//
//	}
//
//	// 根据工序任务删除反馈记录
//	private void deleteRecordByOperationTask(OperationTask operationTask) throws Exception {
//		List<WorkRecord> workRecordList = workRecordManager.findByProperty("taskUid", operationTask.getTaskUid());
//		if (workRecordList != null && workRecordList.size() > 0) {
//			for (WorkRecord workRecord : workRecordList) {
//				workRecordManager.delete(workRecord);
//				operationTask.setCompleteQty(operationTask.getCompleteQty() - workRecord.getCompleteQty());
//			}
//
//		}
//	}
//
//	@Override
//	public void cancelOperationTask(String taskUid) {
//		try {
//			OperationTask operationTask = (OperationTask) this.getById(taskUid);
//			if (operationTask == null) {
//				throw new Exception("未找到工序任务！");
//			}
//			this.cancelOperationTask(operationTask);
//		} catch (Exception e) {
//			e.printStackTrace();
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}
//
//	@Override
//	public void submitOperationTask(String taskUid) {
//		try {
//			OperationTask operationTask = (OperationTask) this.getById(taskUid);
//			if (operationTask == null) {
//				throw new Exception("未找到工序任务！");
//			}
//			this.submitOperationTask(operationTask);
//		} catch (Exception e) {
//			e.printStackTrace();
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//	}
//
//	@Override
//	public void lockOperationTask(OperationTask operationTask) throws Exception {
//		// TODO Auto-generated method stub
//		this.lockOperationTask(operationTask.getTaskUid(), operationTask.getPlanStart(), operationTask.getPlanFinish(),
//				null);
//	}
//
//	@Override
//	public void setTaskActualStart(String taskUid, Date actualStart) throws Exception {
//		OperationTask operationTask = (OperationTask) this.getOperationTaskDAO().findById(taskUid);
//		if (operationTask != null) {
//			operationTask.setActualStart(actualStart);
//			if (operationTask.getTaskState() < OperationTask.TASKSTATE_STARTED) {
//				operationTask.setTaskState(OperationTask.TASKSTATE_STARTED);
//			}
//			this.update(operationTask);
//		}
//	}

	@Override
	public void updateRejectQty(String taskUid, float rejectQty)
			throws Exception {
		log.info("开始设置工序任务报废数-->TASKUID:" + taskUid);
		OperationTask operationTask = this.getById(taskUid);
		if (operationTask == null)
			return;
		
		if (operationTask.getRejectQty() == null)
			operationTask.setRejectQty(rejectQty);
		else {
			operationTask.setRejectQty(operationTask.getRejectQty() + rejectQty);// 设置新的报废数量
		}
		// 任务完成数不能为负的限制
		if (operationTask.getRejectQty() < 0
				|| operationTask.getRejectQty() > operationTask.getCompleteQty()) {
			throw new Exception("报废数反馈错误:报废数小于0 或者 大于任务的完成数!");
		}
		this.update(operationTask);

		// 试件工序的报废不再进行任何处理
		if (operationTask.getTaskType() != null
				&& operationTask.getTaskType().equals(OperationTask.TASKTYPE_SAMPLE))
			return;

		String parentTaskUid = operationTask.getParentTaskUid();
		if (parentTaskUid == null)
			return;

		/**
		 * lqm todo 属于临时解决方法，有待改善 是否允许影响后续任务的工序任务在制数 主要解决由于 单件产出比 工序未准确标识出引起的问题
		 * 一下判断标识属于拆分之前的工序，拆分之前工序的任何报废不影响后续任务的在制数 必须在工序任务已经完成的情况下进行判断
		 * <0.5是为了标示出是拆分之前的工序
		 */
		if (operationTask.getPlanQty() > 0
				&& operationTask.getCompleteQty() / operationTask.getPlanQty() <= 0.5)
			return;

		List<OperationTask> operationTaskList = this.operationTaskDao.getUnFinishTasksByPartTask(parentTaskUid);
		// 先等于当前工序计划数,如果是最后一道工序，则用此工序的数量作为计划数量
		float planQty = operationTask.getPlanQty() - rejectQty;

		if (operationTaskList != null && operationTaskList.size() > 0) {
			float removeQty = rejectQty;
			for (OperationTask tmptask : operationTaskList) {
				// 未完工序和非试样工序,千万注意本道工序不允许作任何更改
				if (!tmptask.getTaskType().equalsIgnoreCase("205")
						&& !tmptask.getTaskUid().equalsIgnoreCase(taskUid)) {
					// 未完成工序的计划数量扣除 removeQty
					if (removeQty > tmptask.getPlanQty()) {
						log.error("报废数反馈错误:不能设置后续工序任务在制数小于!");
						// throw new Exception("报废数反馈错误:不能设置后续工序任务在制数小于!");
					} else {

						tmptask.setPlanQty(tmptask.getPlanQty() - removeQty);
						log.debug("设置工序任务在制数为" + tmptask.getPlanQty() + ",任务为："
								+ tmptask);
					}
					// 如果完成数量大于计划数量，则设置任务为完成，但不设置任务状态
					if (tmptask.getCompleteQty() != null
							&& tmptask.getPlanQty() <= tmptask.getCompleteQty()) {
						// 属于异常补写，不需要刷新工序距离，所以不直接调用finishtask方法
						tmptask.setTaskState(OperationTask.TASKSTATE_COMPLETED);
						// tmptask.setActualFinish(tmptask.getMaxFeedBackDate());
					}
				}
			}
			this.update(operationTaskList);

			// 将计划数量设置成最后一道未完工序的数量
			planQty = operationTaskList.get(operationTaskList.size() - 1).getPlanQty();
		}
		// 更新零件任务在制数量
		partTaskManager.updatePlanQty(parentTaskUid, planQty);
		//当整个零件任务都完成时，将零件任务的完成数量修改与在制数量一致
		PartTask partTask = partTaskManager.getById(parentTaskUid);
		if(partTask.getTaskState() == PartTask.TASKSTATE_COMPLETED){
			partTask.setCompleteQty(partTask.getPlanQty());
			partTaskManager.update(partTask);
		}
		// 如果是整批报废，则如下处理
		if (partTask != null && partTask.getPlanQty().equals(0f))
			partTaskManager.rejectPartTask(parentTaskUid);
		log.info("结束设置工序任务报废数" + taskUid);

	}

//	/**
//	 * by nk
//	 */
//	public List<OperationTask> getSummaryCheckOperationTask(String taskType, String deptId, String drawingId,
//			String batchNum, Integer operationDistance, String invDemandState) {
//		return operationTaskDAO.getSummaryCheckOperationTask(taskType, deptId, drawingId, batchNum, operationDistance,
//				invDemandState);
//	}
//
//	@Override
//	public OperationTask addTempTask(String drawingId, String partName, String batchNum, String operationIdDesc,
//			String taskName, Float planQty, Integer priority) throws Exception {
//		// TODO Auto-generated method stub
//
//		try {
//			Part part = null;
//			List<Part> partList = this.partDAO.getPartsByDrawingId(drawingId);
//			if (partList != null && partList.size() > 0)
//				part = partList.get(0);
//			else {
//				part = new Part();
//				part.setDrawingId(drawingId);
//				part.setPartName(partName);
//				part.setNotes("由临时任务产生");
//				this.partManager.add(part);
//			}
//
//			if (part.getPartUid() == null)
//				return null;
//			OperationTask operationTask = null;
//
//			operationTask = (OperationTask) this.operationTaskDAO.getOperationTask(part.getPartUid(), batchNum,
//					operationIdDesc);
//
//			if (operationTask != null)
//				return operationTask;
//
//			operationTask = new OperationTask();
//			operationTask.setTaskType(OperationTask.TASKTYPE_TEMP);
//			operationTask.setPartUid(part.getPartUid());
//			operationTask.setBatchNum(batchNum);
//			operationTask.setOperationIdDesc(operationIdDesc);
//			operationTask.setTaskName(taskName);
//			// 调度优先级
//			operationTask.setSchedulePriority(priority);
//
//			String deptUid = MMUtils.getSessionDeptId();
//			operationTask.setDeptUid(deptUid);
//			operationTask.setMasterShopUid(deptUid);
//
//			operationTask.setNeedCheck(false);
//
//			operationTask.setPlanQty(planQty == null ? 1 : planQty);
//
//			operationTask.setNotes("临时任务自动产生");
//			this.add(operationTask);
//			return operationTask;
//		} catch (RuntimeException e) {
//			// TODO Auto-generated catch block
//			log.error(e);
//		}
//
//		return null;
//	}
//
//	public List<OperationTask> getOperationTaskByPrepareState(String taskType, String serviceDeptId, String masterShop,
//			String drawingId, String batchNum, Integer taskDistance, String prepareState) {
//		return operationTaskDAO.getOperationTaskByPrepareState(taskType, serviceDeptId, masterShop, drawingId, batchNum,
//				taskDistance, prepareState);
//	}
//
//	@Override
//	public void deliveryOperationTask(String taskUid, String employeeUid) throws Exception {
//		OperationTask operationTask = this.getOperationTaskDAO().getById(taskUid);
//		this.deliveryOperationTask(operationTask, employeeUid);
//
//	}
//
//	@Override
//	public void deliveryOperationTask(OperationTask operationTask, String employeeUid) throws Exception {
//
//		if (operationTask.getTaskState().equals(OperationTask.TASKSTATE_DELIVERIED))
//			return;
//
//		if (operationTask.getTaskState() < OperationTask.TASKSTATE_COMPLETED) {
//			// lqm todo
//			// 以后应该改成添加workrecord时自动添加
//			// 在workRec中记录强制完成操作者,也为调度时自动增加反馈事件
//			WorkRecord workRecord = new WorkRecord();
//			workRecord.setTaskUid(operationTask.getTaskUid());
//			String sessionEmployeeId = MMUtils.getSessionEmployeeId();
//			workRecord.setWorkerUid(employeeUid == null ? sessionEmployeeId : employeeUid);
//			workRecord.setCreatorUid(sessionEmployeeId);
//			// 刚好反馈一个差值
//			workRecord.setCompleteQty(operationTask.getPlanQty()
//					- (operationTask.getCompleteQty() == null ? 0 : operationTask.getCompleteQty()));
//			workRecord.setWorkDate(new Date());
//			workRecord.setCompleteState(WorkRecord.COMPLETESTATE_VALID);
//			workRecord.setNotes("交库完成");
//
//			workRecordManager.add(workRecord);
//
//			this.finishOperationTask(operationTask);
//		}
//		// 自动赋上计划数量值
//		if (operationTask.getCompleteQty() == null || operationTask.getCompleteQty() == 0) {
//			operationTask.setCompleteQty(operationTask.getPlanQty());
//		}
//
//		operationTask.setTaskState(OperationTask.TASKSTATE_DELIVERIED);
//		try {
//			this.update(operationTask);
//		} catch (Exception e) {
//			log.error(e);
//		}
//
//		// 一次交库完成相当于所有前面已经完成的工序交库完成
//
//		boolean deliveyAllCompleteTask = MMUtils.isDeptExist(operationTask.getMasterShopUid(),
//				"task.deliveyAllCompleteTask");
//		if (deliveyAllCompleteTask) {
//			// 取得所有已经处于完成状态的任务
//			List<OperationTask> operationTaskList = this.operationTaskDAO
//					.getOperationTasksByParentUid(operationTask.getParentTaskUid(), OperationTask.TASKSTATE_COMPLETED);
//			if (operationTaskList != null && operationTaskList.size() > 0) {
//				for (OperationTask o : operationTaskList) {
//					if (operationTask.getCompleteQty() == null || operationTask.getCompleteQty().equals(0)) {
//						operationTask.setCompleteQty(operationTask.getPlanQty());
//					}
//					o.setTaskState(OperationTask.TASKSTATE_DELIVERIED);
//				}
//				this.update(operationTaskList);
//			}
//		}
//
//	}
//
//	/**
//	 * 通过部门编号判断是否采集任务的开始时间
//	 *
//	 * @param deptUid
//	 * @return
//	 */
//	public boolean isNeedStartTask(String deptUid) {
//		boolean noneStartTask = false;
//		try {
//			String strDept = MMUtils.getProperty("noneNeedStartDept");
//			if (strDept != null && strDept.length() > 0) {
//				String[] aDept = strDept.split(",");
//				for (String str : aDept) {
//					if (deptUid.startsWith(str)) {
//						noneStartTask = true;
//						break;
//					}
//				}
//			}
//			return noneStartTask;
//		} catch (Exception e) {
//			log.error(e);
//			return false;
//		}
//	}
//
//	/**
//	 * 检查任务反馈的先决条件是否满足 返回值大于=0表示正常 -1 表示不满足前道工序已完成检验的条件
//	 *
//	 * @param taskUid
//	 * @throws Exception--
//	 *
//	 */
//	public FeedbackCondition checkFeedbackCondition(String taskUid) throws Exception {
//		try {
//			OperationTask operationTask = (OperationTask) this.getById(taskUid);
//			if (operationTask == null) {
//				throw new Exception("未找到工序任务！");
//			}
//
//			// 一次交库完成相当于所有前面已经完成的工序交库完成
//
//			boolean feedbackAfterLastOpChecked = MMUtils.isDeptExist(operationTask.getMasterShopUid(),
//					"task.feedbackAfterLastOpChecked");
//			if (feedbackAfterLastOpChecked) {
//				// 非流水的情况
//				if (operationTask.getIsFlow() == null || !operationTask.getIsFlow()) {
//					if (!this.isLastOpChecked(operationTask))
//						return FeedbackCondition.LASTOP_NOT_CHECKED;
//				}
//				// return FeedbackCondition.LASTOP_NOT_CHECKED;
//			}
//
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//		return FeedbackCondition.PASSED;
//
//	}
//
//	@Override
//	public boolean isLastOpChecked(OperationTask operationTask) {
//		// TODO Auto-generated method stub
//		boolean isLastOpChecked = true;
//		Set<OperationTaskLink> linkSet = operationTask.getPredOperationTaskLinks();
//		if (linkSet != null && !linkSet.isEmpty()) {
//			for (OperationTaskLink link : linkSet) {
//
//				this.checkTaskDAO.getCheckTasksByTask(link.getPreOperationTaskUid());
//				// lqm todo
//
//			}
//
//		}
//
//		return false;
//	}

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	private void sendWorkRecScheduleEvent(WorkRecord workRec, OperationTask operationTask) throws Exception {
		if (workRec.getWorkerUid() == null)
			return;

		Employee employee = employeeDao.getById(workRec.getWorkerUid());
		if (employee == null || employee.getDeptUid() == null)
			return;

		// todo
		// 暂时只发送完成消息
		if (operationTask.getTaskState() != OperationTask.TASKSTATE_COMPLETED
				&& operationTask.getTaskState() != OperationTask.TASKSTATE_DELIVERIED)
			return;

		SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		ScheduleEvent scheduleEvent = new ScheduleEvent();

		scheduleEvent.setEventType(ScheduleEvent.EVENTTYPE_ADD_FEEDBACK);
		scheduleEvent.setKeyUid(String.valueOf(workRec.getUniqueId()));

		Element taskElement = new Element("Task");
		taskElement.setAttribute("taskUid", workRec.getTaskUid());
		taskElement.setAttribute("completeQty", String.valueOf(workRec.getCompleteQty()));
		taskElement.setAttribute("taskState", String.valueOf(operationTask.getTaskState()));

		// 开始时间
		Format format = Format.getCompactFormat();
		format.setEncoding("UTF-8");
		format.setIndent("  ");
		XMLOutputter outputter = new XMLOutputter(format);
		scheduleEvent.setEventContent(outputter.outputString(taskElement));

		scheduleEvent.setEventState(ScheduleEvent.EVENTSTATE_DRAFT);

		scheduleEvent.setSourceType("工人反馈");
		scheduleEvent.setSourceUid(workRec.getTaskUid());
		scheduleEvent.setCreatorUid(SysUtil.getSessionEmployeeUid());
		scheduleEvent.setCreateTime(new Date());

		scheduleEventManager.addScheduleEvent(employee.getDeptUid(), scheduleEvent);
		if (operationTask.getPartTask() != null) {
			// 协作任务给请制车间发送调度事件
			String deptUid = operationTask.getPartTask().getMasterShopUid();
			if (!(employee.getDeptUid().startsWith(deptUid)))
				scheduleEventManager.addScheduleEvent(deptUid, scheduleEvent);
		}
	}

}
